Linux内核哈希算法简单理解和注释



inux内核的哈希算法实现
//1、数据结构
struct hashtab_node
{
 void *key;//通过哈希算法得到的关键字
 void *datum;//存储的数据
 struct hashtab_node *next;//单个节点的指针域,形成一个链表
};
//2、这是一张哈希表,hashtab是这张表的首地址
struct hashtab
{
 struct **hashtab_node **htable;
 u32 size;
 u32 nel;
 u32 (*hash_value)(struct hashtab *h,void *key);
 int (*keycmp)(struct hashtab *h,void *key1,void *key2)
};

struct hashtab_info
{
 u32 slots_used;
 u32 max_chain_len;
};
 
struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key),
                               int (*keycmp)(struct hashtab *h, const void *key1, const void *key2),
                               u32 size)//
{
    struct hashtab*p;
 u32 i;
 p = kzalloc(sizeof(*p),GFP_KERNEL);
 if(p == NULL)
  return p;
 p->size = size;//可以存储的节点htable的个数,而且申请的内存是连续的,方便通过key来哈希一个数据位置,直接查找
 p->nel = 0;
 p->keycmp = keycmp;//链表插入时的比较函数
 p->htable = kmalloc(sizeof(*(p->htable)) * size, GFP_KERNEL);//向内核空间申请连续的内存空间
 if (p->htable == NULL)
 {
  kfree(p);
  return NULL;
 }
 
 for (i = 0; i < size; i++)//初始化申请的节点空间
  p->htable[i] = NULL;

 return p;
}

int hashtab_insert(struct hashtab *h, void *key, void *datum)
{
 u32 hvalue;
 struct hashtab_node *prev, *cur, *newnode;
 if(!h || h->nel == HASHTAB_MAX_NODES)//超出数据范围
  return -EINVAL;
  
 hvalue = h->hash_value(h,key);//通过哈希算法得到一个关键字
 prev = NULL;
 cur = h->htable[hvalue];
 while(cur && h->keycmp(h,key,cur->key)>0)
 {
  prev = cur;
  cur = cur->next;
 }//每个hvalue对应下的节点。是一个立体的结构
 
 if (cur && (h->keycmp(h, key, cur->key) == 0))
  return -EEXIST;//存在重复的节点
 
 newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);//构造新的节点
 newnode->key = key;
 newnode->datum = datum;
 if(prev)
 {
  newnode->next = pre->next;
  prev->next = newnode;//插入到指定的位置
 }
 else
 {
  newnode->next = h->htable[hvalue];//成为首节点
  h->htable[hvalue] = newnode;//h->htable[hvalue] 重新指向首节点
 }
 h->nel++;//节点个数加1,这张表中总的节点是size * HASHTAB_MAX_NODES
 return 0;
}
void *hashtab_search(struct hashtab *h, const void *key)
{
 u32 hvalue;
 struct hashtab_node *cur;

 if (!h)
  return NULL;
 
 hvalue = h->hash_value(h, key);
 cur = h->htable[hvalue];//定位到哈希key值的头结点
 
 while (cur != NULL && h->keycmp(h, key, cur->key) > 0)
  cur = cur->next;//遍历整个链表查询

 if (cur == NULL || (h->keycmp(h, key, cur->key) != 0))
  return NULL;

 return cur->datum;//获取到值,找打与key相同的节点
}
void hashtab_destroy(struct hashtab *h)
{
 u32 i;
 struct hashtab_node *cur, *temp; 
 
 if (!h)
  return;
 
 for(i = 0; i < h->size; i++)
 {
  cur = h->htable[i];//每个链表的头结点
  while(cur)
  {
   temp = cur;
   cur = cur->next;
   kfree(temp);
  }
 }
 
    kfree(h->htable);
 h->htable = NULL;

 kfree(h);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值